package com.zyl.Ecs.auth.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.zyl.Ecs.common.domain.auth.bean.Permission;
import com.zyl.Ecs.common.domain.auth.bean.Role;
import com.zyl.Ecs.common.domain.auth.bean.RolePermission;
import com.zyl.Ecs.common.domain.auth.ext.PermissionExt;
import com.zyl.Ecs.common.domain.auth.ext.RoleExt;
import com.zyl.Ecs.auth.mapper.PermissionMapper;
import com.zyl.Ecs.auth.mapper.RoleMapper;
import com.zyl.Ecs.auth.mapper.RolePermissionMapper;
import com.zyl.Ecs.auth.service.RoleService;
import com.zyl.Ecs.common.exception.EcsException;
import com.zyl.Ecs.common.response.ResultCode;
import com.zyl.Ecs.common.utils.ObjectUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;


/**
* @version v1.0
* @Package: com.zyl.Ecs.auth.service.impl
* @ClassName: RoleServiceImpl
* @Description 针对表【base_role】的数据库操作Service实现
* @Author 翟玉龙
* @Date 2024-12-04 16:36:41
*/

@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends MPJBaseServiceImpl<RoleMapper, Role>
    implements RoleService{

    private final RoleMapper roleMapper;
    private final PermissionMapper permissionMapper;
    private final RolePermissionMapper rolePermissionMapper;
    private final IService iService;

    /**
     * 新增角色
     * @param roleExt 角色信息
     * @return {@link RoleExt }
     * @throws EcsException 异常
     */
    @Override
    public RoleExt add(RoleExt roleExt) throws EcsException{
        /* 检查名称是否重复 */
        String name = roleExt.getName();
        checkNameUnique(name, null);

        /* 执行写入 */
        roleExt.setDeleted(0);
        roleMapper.insert(roleExt);

        /* 写入角色信息 */
        setPermissions(roleExt.getId(), roleExt.getPermissionIds(), false);

        /* 查询完整信息并返回 */
        return fillPermissions(roleExt);
    }

    /**
     * 删除角色
     * @param id 角色id
     * @return {@link RoleExt }
     * @throws EcsException 异常
     */
    @Override
    public RoleExt delete(Integer id) throws EcsException{
        RoleExt roleExt = get(id);
        roleMapper.deleteById(id);
        return roleExt;
    }

    /**
     * 更新角色
     * @param roleExt 角色信息
     * @return {@link RoleExt }
     * @throws EcsException 异常
     */
    @Override
    public RoleExt update(RoleExt roleExt) throws EcsException{

        /* 校验id是否存在 */
        Integer id = roleExt.getId();
        internalGet(id);

        /* 校验名称是否重复 */
        String name = roleExt.getName();
        checkNameUnique(name, id);

        /* 执行修改 */
        roleMapper.updateById(roleExt);

        /* 重设用户拥有的角色 */
        setPermissions(id, roleExt.getPermissionIds(), true);

        return roleExt;
    }

    /**
     * 获取角色列表
     * @return {@link List }<{@link RoleExt }>
     * @throws EcsException 异常
     */
    @Override
    public List<RoleExt> getList() throws EcsException{
        List<Role> roles = roleMapper.selectList(null);
        if (ObjectUtil.isEmpty(roles)) {
            return null;
        }
        return iService.fillRPs();
    }

    /**
     * 填充全新权限
     * @param roleExt 角色信息
     * @return {@link RoleExt }
     */
    private RoleExt fillPermissions(RoleExt roleExt) {
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(Wrappers.<RolePermission>
                lambdaQuery().eq(RolePermission::getRoleId, roleExt.getId()));
        if (ObjectUtil.isEmpty(rolePermissions)) {
            return roleExt;
        }
        List<Integer> permissionIds = rolePermissions.stream()
                .map(RolePermission::getPermissionId)
                .collect(Collectors.toList());
        List<Permission> permissions = permissionMapper.selectBatchIds(permissionIds);
        if (ObjectUtil.isEmpty(permissions)) {
            return roleExt;
        }
        roleExt.setPermissions(permissions.stream()
                .map(PermissionExt::toExt)
                .collect(Collectors.toList()));
        return roleExt;
    }

    /**
     * 为用户设置角色
     *
     * @param id           用户id
     * @param permissionIds      角色id列表
     * @param deleteBefore 是否先删除已有角色，新增时不需要，修改时需要
     */
    private void setPermissions(Integer id, List<Integer> permissionIds, boolean deleteBefore) {
        if (deleteBefore) {
            rolePermissionMapper.delete(Wrappers.<RolePermission>lambdaQuery()
                    .eq(RolePermission::getRoleId, id));
        }

        if (ObjectUtil.isEmpty(permissionIds)) {
            return;
        }

        /* 遍历角色id列表，写入用户角色关联数据 */
        permissionIds.forEach(permissionId -> {
            /* 校验角色是否存在 */
            Permission permission = permissionMapper.selectById(permissionId);
            if (ObjectUtil.isNull(permission)) {
                throw new EcsException(ResultCode.PERMISSION_NOT_EXIST);
            }
            rolePermissionMapper.insert(RolePermission.builder()
                    .roleId(id)
                    .permissionId(permissionId)
                    .build());
        });
    }

    /**
     * 检查用户名是否重复
     * @param name 角色名
     * @param id 角色id
     */
    private void checkNameUnique(String name, Integer id) {
        Role record = roleMapper.selectOne(Wrappers.<Role>lambdaQuery()
                .eq(Role::getName, name));
        if (ObjectUtil.nonNull(record) && ObjectUtil.notEquals(record.getId(), id)) {
            throw new EcsException(ResultCode.ROLE_NAME_DUPLICATE);
        }
    }

    private RoleExt get(Integer id) {
        Role role = internalGet(id);
        RoleExt roleExt = RoleExt.toExt(role);
        fillPermissions(roleExt);
        return roleExt;
    }

    private Role internalGet(Integer id) {
        Role role = roleMapper.selectById(id);
        if (ObjectUtil.isNull(role)) {
            throw new EcsException(ResultCode.ACCOUNT_NOT_EXIST);
        }
        return role;
    }
}




